iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 17
0
自我挑戰組

邁向 JavaScript 核心之路 系列 第 17

[Day 17] JavaScript 物件導向- 私有函式與變數、唯獨方法和屬性

  • 分享至 

  • xImage
  •  

私有函式與變數

私有函式與變數是指只有透過內部才可存取操作的函式與變數,前幾天我話好像太多了 XDD,所以今天就直接進入主題,直接來看一段程式碼吧。


    function CreatePerson(name, gender, year) {
        this.name = name;
        this.gender = gender;
        function caclAge(y) {
            var today = new Date();
            return today.getFullYear() - y;
        }
        var age = caclAge(year);
        this.showAge = function() {
            console.log("my age : " + age);
        };
    }
    
    CreatePerson.prototype.showName = function() {
        console.log("my name : " + this.name);
    };
    
    CreatePerson.prototype.showGender = function() {
        console.log("my gender : " + this.gender);
    };
    
    var p1 = new CreatePerson("Reynold", "male", 1993);
    var p2 = new CreatePerson("Cher", "female", 1990);
    

因為我們在函式內設定 age 這個變數與 caclAge 函式,所以在外層,我們是無法存取其值或操作該函式,這樣我們就實作了 私有函式與變數 ,你說這有什麼用?這可好用了,當我們不希望讓人進行存取、操作或變更變數或函式時,我們就可以使用私有函式、變數的技巧來做保護,讓使用者只能經由我們設計的函式來去讀取。

唯獨方法與屬性

我們可以藉由 Object.defineProperty 來建立一個唯獨不可修改的屬性,也可以設定一些特性,我在這邊稍微列舉一些較常用的 defineProperty 的屬性與它對應的功能,若想更了解 defineProperty,我在文末也會附上參考資料哦!。

  • value : 設定值,可以是任何合法的值 ex. number, string, object, function..
  • enumerable : 是否可以被列舉 ex. for in
  • writable : 是否可以被修改值
  • configurable 是否可以刪除屬性或者去變更 enumerable、writable .. 等特性
  • get : 用在取值時所執行的 function。
  • set : 用在設定值時所執行的 function。

如果定義了 get、set,表示要自行控制屬性的存取,就不能再去定義 value 和 writable 屬性

    // 設定唯讀
    
    function CreatePerson() {
        Object.defineProperty(this, "name", {
            value: "Reynold",
            enumerable: true,
            writable: false,
            configurable: true
        });
    }
    
    CreatePerson.prototype.getName = function() {
        console.log(this.name);
    };
    
    var p1 = new CreatePerson();
    p1.getName(); // Reynold
    p1.name = "Ben";
    p1.getName(); // ?
    

各位聰明的讀者,請問最後一個 p1.getName() 顯示出來的會是 Reynold 還是 Ben 呢?

沒錯,答案會是 Reynold 哦,因為我們在上方設定了 writable: false,所以有著唯讀不能被修改的特性哦!

是不是看一個範例不太過癮?
沒問題,再來一個吧!


    var obj = {};
    (function() {
        var _name;
        Object.defineProperty(obj, "name", {
            get: function() {
                console.log("讀取");
                return _name;
            },
            set: function(value) {
                console.log("寫入");
                _name = value;
            }
        })
    })();
    

這邊這個範例非常建議讀者拿去執行看看哦,執行後可以對 obj 作取值或寫值的動作 (obj.name = "" or obj.name ),來觀察它的結果,來確認 get 與 set 是否都有執行。

為人所熟知的 Vue.js 就是利用 get 與 set 來去監聽屬性的異動,並即時的反應在 DOM 上。


參考資料:

Tommy - 深入 JavaScript 核心課程
MDN - Object.defineProperty()


上一篇
[Day 16] JavaScript 物件導向- 原型鏈 ( prototype chain )
下一篇
[Day 18] JavaScript 物件導向- 實字模式
系列文
邁向 JavaScript 核心之路 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言